Shader "Hidden/MobileFog"
{
    Properties
    {
        _MainTex ("Main Texture", 2D) = "white" {}
        _FogGradient ("Fog Gradient", 2D) = "white" {}
    }
    
    SubShader
    {
        Tags { "RenderType"="Opaque" "RenderPipeline"="UniversalPipeline" }
        ZTest Always ZWrite Off Cull Off
        
        Pass
        {
            Name "MobileFog"
            
            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_local _ _USE_FAST_MODE
            #pragma multi_compile_local _ _USE_GRADIENT_COLOR
            
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
            
            struct Attributes
            {
                float4 positionOS : POSITION;
                float2 uv : TEXCOORD0;
            };
            
            struct Varyings
            {
                float4 positionHCS : SV_POSITION;
                float2 uv : TEXCOORD0;
                float3 viewVector : TEXCOORD1;
            };
            
            TEXTURE2D(_MainTex);
            SAMPLER(sampler_MainTex);
            TEXTURE2D(_FogGradient);
            SAMPLER(sampler_FogGradient);
            
            // 雾效参数
            float _FogDensity;
            float _FogStart;
            float _FogEnd;
            float _HeightFogDensity;
            float _HeightFogBase;
            float _HeightFogRange;
            float4 _FogColor;
            float4 _FogColorNear;
            float4 _FogColorFar;
            float _GradientDistance;
            float _UseGradientColor;
            float _Intensity;
            float _UseFastMode;
            
            // 噪波参数
            float _NoiseScale;
            float _NoiseIntensity;
            float _NoiseSpeed;
            
            Varyings vert(Attributes input)
            {
                Varyings output;
                output.positionHCS = TransformObjectToHClip(input.positionOS.xyz);
                output.uv = input.uv;
                
                // 计算视图向量，用于重建世界坐标
                float4 clipPos = float4(input.uv * 2.0 - 1.0, 1.0, 1.0);
                float4 viewPos = mul(unity_CameraInvProjection, clipPos);
                output.viewVector = viewPos.xyz / viewPos.w;
                
                return output;
            }
            
            // 简单的2D噪波函数
            float random(float2 st) 
            {
                return frac(sin(dot(st.xy, float2(12.9898,78.233))) * 43758.5453123);
            }
            
            // Perlin噪波近似
            float noise(float2 st) 
            {
                float2 i = floor(st);
                float2 f = frac(st);
                
                // 四个角的随机值
                float a = random(i);
                float b = random(i + float2(1.0, 0.0));
                float c = random(i + float2(0.0, 1.0));
                float d = random(i + float2(1.0, 1.0));
                
                // 平滑插值
                float2 u = f * f * (3.0 - 2.0 * f);
                
                return lerp(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y;
            }
            
            // 分形噪波
            float fbm(float2 st, int octaves) 
            {
                float value = 0.0;
                float amplitude = 0.5;
                float frequency = 1.0;
                
                for (int i = 0; i < octaves; i++) 
                {
                    value += amplitude * noise(st * frequency);
                    amplitude *= 0.5;
                    frequency *= 2.0;
                }
                return value;
            }
            
            // 根据距离获取雾的颜色
            float3 GetFogColor(float depth)
            {
                if (_UseGradientColor > 0.5)
                {
                    // 计算距离插值因子 (0=近处, 1=远处)
                    float distanceFactor = saturate((depth - _FogStart) / max(_GradientDistance, 0.001));
                    
                    // 在近处和远处颜色之间插值
                    return lerp(_FogColorNear.rgb, _FogColorFar.rgb, distanceFactor);
                }
                else
                {
                    // 使用固定颜色
                    return _FogColor.rgb;
                }
            }
            
            // 从渐变贴图采样颜色（可选的高级功能）
            float3 GetFogColorFromTexture(float depth)
            {
                // 将深度映射到0-1范围
                float t = saturate((depth - _FogStart) / max(_GradientDistance, 0.001));
                return SAMPLE_TEXTURE2D_LOD(_FogGradient, sampler_FogGradient, float2(t, 0.5), 0).rgb;
            }
            
            // 计算基础深度雾（不受高度影响）
            float CalculateDepthFog(float depth)
            {
                return saturate((depth - _FogStart) / max(_FogEnd - _FogStart, 0.001)) * _FogDensity;
            }
            
            // 计算基础深度雾（精确模式）
            float CalculateDepthFogPrecise(float depth)
            {
                return 1.0 - exp(-_FogDensity * max(depth - _FogStart, 0.0));
            }
            
            // 计算带噪波的高度因子（0-1，用于调节深度雾密度）
            float CalculateHeightFactorWithNoise(float height, float3 worldPos)
            {
                // 基础高度计算
                float heightOffset = height - _HeightFogBase;
                
                // 添加基于世界坐标的噪波扰动
                float2 noiseCoord = worldPos.xz * _NoiseScale + _Time.y * _NoiseSpeed;
                
                // 生成多层噪波
                float heightNoise = fbm(noiseCoord, 3) * 2.0 - 1.0; // -1 到 1
                float detailNoise = fbm(noiseCoord * 3.0, 2) * 0.5; // 细节噪波
                
                // 组合噪波
                float combinedNoise = (heightNoise + detailNoise * 0.3) * _NoiseIntensity;
                
                // 将噪波应用到高度偏移
                float noisyHeightOffset = heightOffset + combinedNoise;
                
                // 计算标准化高度，使用更平滑的过渡
                float normalizedHeight = noisyHeightOffset / max(_HeightFogRange, 0.001);
                
                // 使用更自然的衰减曲线 (高度越低值越大，高度越高值越小)
                float heightFactor = 1.0 / (1.0 + exp(normalizedHeight * 4.0 - 2.0)); // sigmoid函数
                
                return heightFactor;
            }
            
            // 快速雾效计算（移动端优化）
            float CalculateFogFast(float depth, float height, float3 worldPos)
            {
                // 计算独立的深度雾
                float depthFog = CalculateDepthFog(depth);
                
                // 计算高度调节因子 (0-1)
                float heightFactor = CalculateHeightFactorWithNoise(height, worldPos);
                
                // 计算独立的高度雾
                float heightFog = _HeightFogDensity * heightFactor;
                
                // 深度雾受高度影响：高度越低，深度雾越浓
                float heightInfluencedDepthFog = depthFog * lerp(0.1, 1.0, heightFactor);
                
                // 组合两种雾效：使用加法混合，但避免过饱和
                float combinedFog = heightInfluencedDepthFog + heightFog;
                
                return saturate(combinedFog);
            }
            
            // 高质量雾效计算
            float CalculateFogPrecise(float depth, float height, float3 worldPos)
            {
                // 计算独立的指数深度雾
                float depthFog = CalculateDepthFogPrecise(depth);
                
                // 计算带噪波的平滑高度调节因子
                float heightFactor = CalculateHeightFactorWithNoise(height, worldPos);
                heightFactor = smoothstep(0.0, 1.0, heightFactor);
                
                // 计算独立的高度雾
                float heightFog = _HeightFogDensity * heightFactor;
                
                // 深度雾受高度影响：使用更平滑的过渡
                float heightInfluencedDepthFog = depthFog * lerp(0.1, 1.0, heightFactor);
                
                // 使用更自然的组合方式：乘法混合避免过度叠加
                float combinedFog = 1.0 - (1.0 - heightInfluencedDepthFog) * (1.0 - heightFog);
                
                return saturate(combinedFog);
            }
            
            float4 frag(Varyings input) : SV_Target
            {
                float4 color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, input.uv);
                
                // 采样深度并转换为线性深度
                float depth = SampleSceneDepth(input.uv);
                float linearDepth = LinearEyeDepth(depth, _ZBufferParams);
                
                // 重建世界坐标以获取高度信息
                float3 worldPos = _WorldSpaceCameraPos + input.viewVector * linearDepth;
                float height = worldPos.y;
                
                // 根据设置选择计算模式
                float fogFactor;
                if (_UseFastMode > 0.5)
                {
                    fogFactor = CalculateFogFast(linearDepth, height, worldPos);
                }
                else
                {
                    fogFactor = CalculateFogPrecise(linearDepth, height, worldPos);
                }
                
                // 应用强度控制
                fogFactor *= _Intensity;
                
                // 根据距离获取雾的颜色
                float3 fogColor = GetFogColor(linearDepth);
                
                // 混合原色和雾色
                float3 finalColor = lerp(color.rgb, fogColor, fogFactor);
                
                return float4(finalColor, color.a);
            }
            ENDHLSL
        }
    }
    
    Fallback Off
}